package com.safe.first.infrastructure.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @author Mickey
 * @since 2022/6/10
 **/
@Slf4j
@Component
public class MyUsernamePasswordAuthenticationFilter extends MyAbstractAuthenticationProcessingFilter {

    private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/login",
            "POST");

    public MyUsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager,
                                                  MySavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler,
                                                  MySimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler) {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
        setAuthenticationSuccessHandler(savedRequestAwareAuthenticationSuccessHandler);
        setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler);
    }

    @Override
    public Authentication attemptAuthentication(Map<String, String> params, HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        String username = params.get("username");
        String password = params.get("password");
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);
        return this.getAuthenticationManager().authenticate(authRequest);
    }

    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
    }
}
